﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Drawing;
using ITAP.Core.Calculations;
using ITAP.Core.Modelling.Primitives;
using ITAP.Core.Modelling;

namespace ITAP.ContourBuilder.ContourRender
{
    public class PrimitiveRender : IPrimitiveVisitor
    {

        private Graphics graphics;
        private int screenWidth;
        private int screenHeight;
        private RectangleF modelRectangle;
        private ModelPoint centerPoint;
        private ModelCoordinateConverter coordinateConverter;

        private Pen pen;

        public Pen Pen
        {
            get { return pen; }
            set { pen = value; }
        }       

        public void Initialize(Graphics graphics, int screenWidth, int screenHeight, RectangleF modelRectangle, ModelCoordinateConverter coordinateConverter, ModelPoint centerPoint)
        {

            this.graphics = graphics;
            this.screenWidth = screenWidth;
            this.screenHeight = screenHeight;
            this.modelRectangle = modelRectangle;
            this.centerPoint = centerPoint;
            this.coordinateConverter = coordinateConverter;
            this.coordinateConverter.RecalculateAutoScale(screenWidth, screenHeight, modelRectangle);
        }

        #region IPrimitiveVisitor Members

        public void Visit(ITAP.Core.Modelling.Primitives.Line line)
        {
            PointF startPoint = this.coordinateConverter.ModelPointToScreenPoint(line.StartPoint, screenWidth, screenHeight, modelRectangle, this.centerPoint);
            PointF endPoint = this.coordinateConverter.ModelPointToScreenPoint(line.EndPoint, screenWidth, screenHeight, modelRectangle, this.centerPoint);
            this.graphics.DrawLine(this.pen, startPoint, endPoint);
        }

        public void Visit(ITAP.Core.Modelling.Primitives.Circle circle)
        {
            RectangleF rect;
            float startAngle;
            float sweepAngle;

            this.GetArcParameters(circle, out rect, out startAngle, out sweepAngle);
            graphics.DrawArc(this.pen, rect, startAngle, sweepAngle);
        }

        public void Visit(ITAP.Core.Modelling.Primitives.CompositePrimitive compositePrimitive)
        {
            foreach (IPrimitive innerPrimitive in compositePrimitive.InnerPrimitives)
                innerPrimitive.AcceptVisitor(this);
        }

        #endregion

        public virtual void GetArcParameters(Circle circle, out RectangleF rectangle, out float startAngle, out float sweepAngle)
        {
            PointF center = coordinateConverter.ModelPointToScreenPoint(circle.Center, screenWidth, screenHeight, modelRectangle, this.centerPoint);
            float radius = coordinateConverter.ModelMeasureToScreenMeasure((float)circle.Radius, screenWidth, screenHeight, modelRectangle);
            rectangle = new RectangleF(center.X - radius, center.Y - radius, radius * 2, radius * 2);
            if (circle.Height > 0)
            {
                startAngle = (float)(360 - circle.EndAngle.Value * 180 / Math.PI);
            }
            else
            {
                startAngle = (float)(360 - circle.StartAngle.Value * 180 / Math.PI);
            }
            sweepAngle = (float)(circle.Angle.Value * 180 / Math.PI);
        }

    }
}
